{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Sample for KFServing SDK v1beta1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is a sample for KFServing SDK v1beta1. \n",
    "\n",
    "The notebook shows how to use KFServing SDK to create, get and delete InferenceService."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from kubernetes import client\n",
    "from kfserving import KFServingClient\n",
    "from kfserving import constants\n",
    "from kfserving import utils\n",
    "from kfserving import V1beta1InferenceService\n",
    "from kfserving import V1beta1InferenceServiceSpec\n",
    "from kfserving import V1beta1PredictorSpec\n",
    "from kfserving import V1beta1TFServingSpec"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define namespace where InferenceService needs to be deployed to. If not specified, below function defines namespace to the current one where SDK is running in the cluster, otherwise it will deploy to default namespace."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# namespace = utils.get_default_target_namespace()\n",
    "namespace = \"kfserving-test\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define InferenceService"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Firstly define default endpoint spec, and then define the inferenceservice basic on the endpoint spec."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "api_version = constants.KFSERVING_GROUP + \"/\" + kfserving_version\n",
    "\n",
    "isvc = V1beta1InferenceService(\n",
    "    api_version=api_version,\n",
    "    kind=constants.KFSERVING_KIND,\n",
    "    metadata=client.V1ObjectMeta(name=\"flower-sample\", namespace=namespace),\n",
    "    spec=V1beta1InferenceServiceSpec(\n",
    "        predictor=V1beta1PredictorSpec(\n",
    "            tensorflow=(\n",
    "                V1beta1TFServingSpec(\n",
    "                    storage_uri=\"gs://kfserving-examples/models/tensorflow/flowers\"\n",
    "                )\n",
    "            )\n",
    "        )\n",
    "    ),\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create InferenceService"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Call KFServingClient to create InferenceService."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'apiVersion': 'serving.kserve.io/v1beta1',\n",
       " 'kind': 'InferenceService',\n",
       " 'metadata': {'creationTimestamp': '2021-01-18T00:31:35Z',\n",
       "  'generation': 1,\n",
       "  'name': 'flower-sample',\n",
       "  'namespace': 'kfserving-test',\n",
       "  'resourceVersion': '283999021',\n",
       "  'selfLink': '/apis/serving.kserve.io/v1beta1/namespaces/kfserving-test/inferenceservices/flower-sample',\n",
       "  'uid': 'd074779a-e0d0-4612-b9c7-a7da69002683'},\n",
       " 'spec': {'predictor': {'tensorflow': {'name': 'kfserving-container',\n",
       "    'resources': {'limits': {'cpu': '1', 'memory': '2Gi'},\n",
       "     'requests': {'cpu': '1', 'memory': '2Gi'}},\n",
       "    'runtimeVersion': '1.14.0',\n",
       "    'storageUri': 'gs://kfserving-examples/models/tensorflow/flowers'}}}}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "KFServing = KFServingClient()\n",
    "KFServing.create(isvc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Check the InferenceService"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NAME                 READY                           PREV                    LATEST URL                                                              \n",
      "flower-sample        True                               0                       100 http://flower-sample.kfserving-test.example.com                  \n"
     ]
    }
   ],
   "source": [
    "KFServing.get(\"flower-sample\", namespace=namespace, watch=True, timeout_seconds=120)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Patch the InferenceService and define Canary Traffic Percent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'apiVersion': 'serving.kserve.io/v1beta1',\n",
       " 'kind': 'InferenceService',\n",
       " 'metadata': {'creationTimestamp': '2021-01-18T00:31:35Z',\n",
       "  'finalizers': ['inferenceservice.finalizers'],\n",
       "  'generation': 2,\n",
       "  'name': 'flower-sample',\n",
       "  'namespace': 'kfserving-test',\n",
       "  'resourceVersion': '283999615',\n",
       "  'selfLink': '/apis/serving.kserve.io/v1beta1/namespaces/kfserving-test/inferenceservices/flower-sample',\n",
       "  'uid': 'd074779a-e0d0-4612-b9c7-a7da69002683'},\n",
       " 'spec': {'predictor': {'canaryTrafficPercent': 20,\n",
       "   'tensorflow': {'name': 'kfserving-container',\n",
       "    'resources': {'limits': {'cpu': '1', 'memory': '2Gi'},\n",
       "     'requests': {'cpu': '1', 'memory': '2Gi'}},\n",
       "    'runtimeVersion': '1.14.0',\n",
       "    'storageUri': 'gs://kfserving-examples/models/tensorflow/flowers-2'}}},\n",
       " 'status': {'address': {'url': 'http://flower-sample.kfserving-test.svc.cluster.local/v1/models/flower-sample:predict'},\n",
       "  'components': {'predictor': {'address': {'url': 'http://flower-sample-predictor-default.kfserving-test.svc.cluster.local'},\n",
       "    'latestCreatedRevision': 'flower-sample-predictor-default-fg4d6',\n",
       "    'latestReadyRevision': 'flower-sample-predictor-default-fg4d6',\n",
       "    'latestRolledoutRevision': 'flower-sample-predictor-default-fg4d6',\n",
       "    'traffic': [{'latestRevision': True,\n",
       "      'percent': 100,\n",
       "      'revisionName': 'flower-sample-predictor-default-fg4d6',\n",
       "      'tag': 'latest',\n",
       "      'url': 'http://latest-flower-sample-predictor-default.kfserving-test.example.com'}],\n",
       "    'url': 'http://flower-sample-predictor-default.kfserving-test.example.com'}},\n",
       "  'conditions': [{'lastTransitionTime': '2021-01-18T00:31:55Z',\n",
       "    'status': 'True',\n",
       "    'type': 'IngressReady'},\n",
       "   {'lastTransitionTime': '2021-01-18T00:31:55Z',\n",
       "    'severity': 'Info',\n",
       "    'status': 'True',\n",
       "    'type': 'PredictorConfigurationReady'},\n",
       "   {'lastTransitionTime': '2021-01-18T00:31:55Z',\n",
       "    'status': 'True',\n",
       "    'type': 'PredictorReady'},\n",
       "   {'lastTransitionTime': '2021-01-18T00:31:51Z',\n",
       "    'severity': 'Info',\n",
       "    'status': 'True',\n",
       "    'type': 'PredictorRouteReady'},\n",
       "   {'lastTransitionTime': '2021-01-18T00:31:55Z',\n",
       "    'status': 'True',\n",
       "    'type': 'Ready'}],\n",
       "  'url': 'http://flower-sample.kfserving-test.example.com'}}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isvc = V1beta1InferenceService(\n",
    "    api_version=api_version,\n",
    "    kind=constants.KFSERVING_KIND,\n",
    "    metadata=client.V1ObjectMeta(name=\"flower-sample\", namespace=namespace),\n",
    "    spec=V1beta1InferenceServiceSpec(\n",
    "        predictor=V1beta1PredictorSpec(\n",
    "            canary_traffic_percent=20,\n",
    "            tensorflow=(\n",
    "                V1beta1TFServingSpec(\n",
    "                    storage_uri=\"gs://kfserving-examples/models/tensorflow/flowers-2\"\n",
    "                )\n",
    "            ),\n",
    "        )\n",
    "    ),\n",
    ")\n",
    "\n",
    "KFServing.patch(\"flower-sample\", isvc, namespace=namespace)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Check the InferenceService after Patching"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "KFServing.wait_isvc_ready(\"flower-sample\", namespace=namespace)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NAME                 READY                           PREV                    LATEST URL                                                              \n",
      "flower-sample        True                              80                        20 http://flower-sample.kfserving-test.example.com                  \n"
     ]
    }
   ],
   "source": [
    "KFServing.get(\"flower-sample\", namespace=namespace, watch=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Delete the InferenceService"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'apiVersion': 'serving.kserve.io/v1alpha2',\n",
       " 'kind': 'InferenceService',\n",
       " 'metadata': {'creationTimestamp': '2021-01-18T00:21:55Z',\n",
       "  'deletionGracePeriodSeconds': 0,\n",
       "  'deletionTimestamp': '2021-01-18T00:24:37Z',\n",
       "  'finalizers': ['inferenceservice.finalizers'],\n",
       "  'generation': 3,\n",
       "  'name': 'flower-sample',\n",
       "  'namespace': 'kfserving-test',\n",
       "  'resourceVersion': '283995283',\n",
       "  'selfLink': '/apis/serving.kserve.io/v1alpha2/namespaces/kfserving-test/inferenceservices/flower-sample',\n",
       "  'uid': 'd2b1aeb1-8029-41fc-a614-1ed65949a797'},\n",
       " 'spec': {'canaryTrafficPercent': 20,\n",
       "  'default': {'predictor': {'tensorflow': {'resources': {'limits': {'cpu': '1',\n",
       "       'memory': '2Gi'},\n",
       "      'requests': {'cpu': '1', 'memory': '2Gi'}},\n",
       "     'runtimeVersion': '1.14.0',\n",
       "     'storageUri': 'gs://kfserving-examples/models/tensorflow/flowers-2'}}}},\n",
       " 'status': {}}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "KFServing.delete(\"flower-sample\", namespace=namespace)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
